From 25d74aa44658ee45dfa9d3133f1e2cb6496eb47e Mon Sep 17 00:00:00 2001 From: "sos22@douglas.cl.cam.ac.uk" Date: Fri, 8 Jul 2005 15:35:43 +0000 Subject: [PATCH] Certain types of event channel are now auto-bound to vcpu0 by Xen. Make sure that xenolinux agrees with this. --- .../arch/xen/i386/kernel/smpboot.c | 4 ++-- .../arch/xen/kernel/ctrl_if.c | 3 +++ .../arch/xen/kernel/evtchn.c | 19 ++++++++++++++++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c index 4798f1d4ec..215cff15b3 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -1533,13 +1533,13 @@ void __init smp_intr_init(void) int cpu = smp_processor_id(); per_cpu(resched_irq, cpu) = - bind_ipi_to_irq(RESCHEDULE_VECTOR); + bind_ipi_on_cpu_to_irq(RESCHEDULE_VECTOR); sprintf(resched_name[cpu], "resched%d", cpu); BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, SA_INTERRUPT, resched_name[cpu], NULL)); per_cpu(callfunc_irq, cpu) = - bind_ipi_to_irq(CALL_FUNCTION_VECTOR); + bind_ipi_on_cpu_to_irq(CALL_FUNCTION_VECTOR); sprintf(callfunc_name[cpu], "callfunc%d", cpu); BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), smp_call_function_interrupt, diff --git a/linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c index c1cfb82dbd..733103f475 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c @@ -491,6 +491,8 @@ void ctrl_if_resume(void) * pick up its end of the event channel from */ evtchn_op_t op; + extern void bind_evtchn_to_cpu(unsigned port, unsigned cpu); + op.cmd = EVTCHNOP_bind_interdomain; op.u.bind_interdomain.dom1 = DOMID_SELF; op.u.bind_interdomain.dom2 = DOMID_SELF; @@ -500,6 +502,7 @@ void ctrl_if_resume(void) BUG(); xen_start_info.domain_controller_evtchn = op.u.bind_interdomain.port1; initdom_ctrlif_domcontroller_port = op.u.bind_interdomain.port2; + bind_evtchn_to_cpu(op.u.bind_interdomain.port1, 0); } /* Sync up with shared indexes. */ diff --git a/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c index b293eee001..7db8ee5e8d 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c @@ -86,7 +86,7 @@ static u32 cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/32]; cpu_evtchn_mask[cpu][idx] & \ ~(sh)->evtchn_mask[idx]) -static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) +void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) { clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]); set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]); @@ -99,8 +99,9 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) ((sh)->evtchn_pending[idx] & \ ~(sh)->evtchn_mask[idx]) -#define bind_evtchn_to_cpu(chn,cpu) ((void)0) - +void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) +{ +} #endif /* Upcall to generic IRQ layer. */ @@ -228,6 +229,13 @@ void unbind_virq_from_irq(int virq) if ( HYPERVISOR_event_channel_op(&op) != 0 ) panic("Failed to unbind virtual IRQ %d\n", virq); + /* This is a slight hack. Interdomain ports can be allocated + directly by userspace, and at that point they get bound by + Xen to vcpu 0. We therefore need to make sure that if we + get an event on an event channel we don't know about vcpu 0 + handles it. Binding channels to vcpu 0 when closing them + achieves this. */ + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = -1; irq_to_evtchn[irq] = -1; per_cpu(virq_to_irq, cpu)[virq] = -1; @@ -320,6 +328,8 @@ void unbind_ipi_from_irq(int ipi) if ( HYPERVISOR_event_channel_op(&op) != 0 ) panic("Failed to unbind virtual IPI %d on cpu %d\n", ipi, cpu); + /* See comments in unbind_virq_from_irq */ + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = -1; irq_to_evtchn[irq] = -1; per_cpu(ipi_to_evtchn, cpu)[ipi] = 0; @@ -474,6 +484,7 @@ static unsigned int startup_pirq(unsigned int irq) pirq_query_unmask(irq_to_pirq(irq)); + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = irq; irq_to_evtchn[irq] = evtchn; @@ -499,6 +510,7 @@ static void shutdown_pirq(unsigned int irq) if ( HYPERVISOR_event_channel_op(&op) != 0 ) panic("Failed to unbind physical IRQ %d\n", irq); + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = -1; irq_to_evtchn[irq] = -1; } @@ -598,6 +610,7 @@ void irq_resume(void) evtchn = op.u.bind_virq.port; /* Record the new mapping. */ + bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = irq; irq_to_evtchn[irq] = evtchn; -- 2.30.2